package com.ruoyi.common.utils.uuid;

import com.ruoyi.common.utils.encode.Base62;

import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

/**
 * ID生成器工具类
 * 
 * @author ruoyi
 */
public class IdUtils
{
    // 时间格式（精确到毫秒）15位
    private static final DateTimeFormatter ORDER_TIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyMMddHHmmssSSS");

    // 时间格式（精确到日）6位
    private static final DateTimeFormatter DIS_TIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyMMdd");

    /**
     * 生成24位微信交易订单号
     *
     * 结构：[版本标识2位][时间戳12位][随机值10位]
     * 示例：WX240315142536ABCD1234
     */
    public static String generateTransactionId() {
        // 1. 版本标识（固定为'K'）
        String version = "WX";

        // 2. 获取当前时间戳（12位：yyMMddHHmmss）
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));

        // 3. 生成11位随机值（高性能随机数）
        String randomPart = generateRandomString(10, false);

        return version + timestamp + randomPart;
    }

    /**
     * 生成24位退款单编号
     *
     * 结构：[版本标识2位][时间戳12位][随机值10位]
     * 示例：RT240315142536ABCD1234
     */
    public static String generateRefundNo() {
        // 1. 版本标识（固定为"RT"）
        String version = "RT";

        // 2. 获取当前时间戳（12位：yyMMddHHmmss）
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));

        // 3. 生成8位随机值（高性能随机数）
        String randomPart = generateRandomString(10, true);

        return version + timestamp + randomPart;
    }

    /**
     * 生成24位订单号
     *
     * 结构：[版本标识2位][时间戳12位][随机值10位]
     * 示例：OT240315142536ABCD1234
     */
    public static String generateOrderCodeV2() {
        // 1. 版本标识（固定为'K'）
        String version = "OT";

        // 2. 获取当前时间戳（12位：yyMMddHHmmss）
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));

        // 3. 生成11位随机值（高性能随机数）
        String randomPart = generateRandomString(10, false);

        return version + timestamp + randomPart;
    }

    /**
     * 生成指定长度的随机字符串
     *
     * @param length 字符串长度
     * @param numericOnly 是否仅数字
     * @return 随机字符串
     */
    private static String generateRandomString(int length, boolean numericOnly) {
        // 数字+大写字母字符集
        String charSet = numericOnly ? "0123456789" : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] result = new char[length];
        ThreadLocalRandom random = ThreadLocalRandom.current();

        for (int i = 0; i < length; i++) {
            result[i] = charSet.charAt(random.nextInt(charSet.length()));
        }

        return new String(result);
    }

    // -------------------------------------------------------- //

    /**
     * 生成24位微信交易订单号
     *
     * 结构：[版本标识3位][时间戳12位][随机值9位]
     * 示例：WX240315142536ABCD1234
     */
    public static String generateLogCode() {
        // 1. 版本标识（固定为'K'）
        String version = "LOG";

        // 2. 获取当前时间戳（12位：yyMMddHHmmss）
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));

        // 3. 生成11位随机值（高性能随机数）
        String randomPart = generateRandomString(9, false);

        return version + timestamp + randomPart;
    }

    /**
     * 生成优化的24位订单号
     * generateWithdrawCode
     * 结构：[版本标识3位][时间戳6位][随机值4位]
     *
     * @return 13位订单号
     */
    public static String generateDistributorCode() {
        // 1. 版本标识（固定为'K'）
        String version = "DSN";

        // 2. 获取当前时间戳（6位）
        String timestamp = LocalDateTime.now().format(DIS_TIME_FORMATTER);

        // 3. 生成16位随机值（高性能随机数）
        String randomPart = generateRandomHex(4);

        return version + timestamp + randomPart;
    }

    /**
     * 生成优化的24位订单号
     *
     * 结构：[版本标识3位][时间戳12位][随机值9位]
     *
     * @return 13位订单号
     */
    public static String generateWithdrawCode() {
        // 1. 版本标识（固定为'K'）
        String version = "WDC";

        // 2. 获取当前时间戳（6位）
        String timestamp = LocalDateTime.now().format(ORDER_TIME_FORMATTER);

        // 2. 获取当前时间戳（12位：yyMMddHHmmss）
//        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss"));

        // 3. 生成16位随机值（高性能随机数）
        String randomPart = generateRandomHex(9);

        return version + timestamp + randomPart;
    }

    /**
     * 生成优化的24位订单号
     *
     * 结构：[版本标识1位][时间戳15位][随机值8位]
     *
     * @return 24位订单号
     */
    public static String generateOrderCode() {
        // 1. 版本标识（固定为'K'）
        char version = 'K';

        // 2. 获取当前时间戳（15位）
        String timestamp = LocalDateTime.now().format(ORDER_TIME_FORMATTER);

        // 3. 生成16位随机值（高性能随机数）
        String randomPart = generateRandomHex(8);

        return version + timestamp + randomPart;
    }

    /**
     * 生成优化的24位订单号
     *
     * 结构：[版本标识2位][时间戳15位][随机值7位]
     *
     * @return 24位订单号
     */
    public static String generateOrderDetailCode() {
        // 1. 版本标识（固定为'K'）
        String version = "KD";

        // 2. 获取当前时间戳（15位）
        String timestamp = LocalDateTime.now().format(ORDER_TIME_FORMATTER);

        // 3. 生成16位随机值（高性能随机数）
        String randomPart = generateRandomHex(7);

        return version + timestamp + randomPart;
    }

    /**
     * 生成优化的24位退款单号
     *
     * 结构：[版本标识1位][时间戳15位][随机值8位]
     *
     * @return 24位订单号
     */
    public static String generateRefundCode() {
        // 1. 版本标识（固定为'R'）
        char version = 'R';

        // 2. 获取当前时间戳（15位）
        String timestamp = LocalDateTime.now().format(ORDER_TIME_FORMATTER);

        // 3. 生成16位随机值（高性能随机数）
        String randomPart = generateRandomHex(8);

        return version + timestamp + randomPart;
    }


    /**
     * 生成指定长度的随机十六进制字符串
     */
    private static String generateRandomHex(int length) {
        char[] hexChars = "0123456789ABCDEF".toCharArray();
        char[] result = new char[length];

        ThreadLocalRandom random = ThreadLocalRandom.current();
        for (int i = 0; i < length; i++) {
            result[i] = hexChars[random.nextInt(hexChars.length)];
        }
        return new String(result);
    }


    // -------------------------------------------------------- //




    // 格式：时间戳(10位) + 随机数(4位)
    public static String GoodsCodeI() {
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String random = String.format("%04d", new Random().nextInt(10000));
        return timestamp + random;
    }

    // 使用Base62压缩UUID（原32字符→22字符）
    public static String GoodsCodeII() {
        UUID uuid = UUID.randomUUID();
        // 使用 allocate 替代 wrap 提高性能
        ByteBuffer bb = ByteBuffer.allocate(16);
        bb.putLong(uuid.getMostSignificantBits());
        bb.putLong(uuid.getLeastSignificantBits());

        // 添加空值检查
        byte[] bytes = bb.array();
        if (bytes == null || bytes.length == 0) {
            throw new IllegalArgumentException("Invalid UUID bytes");
        }

        return Base62.encode(bytes);
    }



    // -------------------------------------------------------- //


    /**
     * 获取随机UUID
     * 
     * @return 随机UUID
     */
    public static String randomUUID()
    {
        return UUID.randomUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线
     * 
     * @return 简化的UUID，去掉了横线
     */
    public static String simpleUUID()
    {
        return UUID.randomUUID().toString(true);
    }

    /**
     * 获取随机UUID，使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 随机UUID
     */
    public static String fastUUID()
    {
        return UUID.fastUUID().toString();
    }

    /**
     * 简化的UUID，去掉了横线，使用性能更好的ThreadLocalRandom生成UUID
     * 
     * @return 简化的UUID，去掉了横线
     */
    public static String fastSimpleUUID()
    {
        LocalDateTime  now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        String formattedDateTime = now.format(formatter);
        return UUID.fastUUID().toString(true) + formattedDateTime;
    }

    /**
     * 生成10位商户号
     * 结构：[时间戳后5位][5位随机数]
     * 示例：1234567890 → 23456（时间戳后5位） + 78901（随机数）
     *
     * @return 10位商户号
     */
    public static String generateMerchantCode() {
        // 1. 获取当前毫秒数的后5位
        long currentMillis = System.currentTimeMillis();
        String timestamp = String.format("%05d", (int) (currentMillis % 100000));

        // 2. 生成5位随机数（00000 - 99999）
        int randomNum = ThreadLocalRandom.current().nextInt(0, 100000);
        String random = String.format("%05d", randomNum);

        return timestamp + random;
    }

}
